package com.taxx.util;

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 数据校验工具类
 * 
 * @author taxx
 * @since 2024-01-01
 */
@Slf4j
public class ValidationUtil {

    // 统一社会信用代码正则表达式（18位）
    private static final Pattern CREDIT_CODE_PATTERN = Pattern.compile("^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$");
    
    // 手机号码正则表达式
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
    
    // 邮箱正则表达式
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
    
    // URL正则表达式
    private static final Pattern URL_PATTERN = Pattern.compile("^(https?://)?([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$");

    /**
     * 校验字符串是否为空
     */
    public static boolean isEmpty(String value) {
        return value == null || value.trim().isEmpty();
    }

    /**
     * 校验字符串是否不为空
     */
    public static boolean isNotEmpty(String value) {
        return !isEmpty(value);
    }

    /**
     * 校验字符串长度是否在指定范围内
     */
    public static boolean isLengthInRange(String value, int minLength, int maxLength) {
        if (isEmpty(value)) {
            return false;
        }
        int length = value.trim().length();
        return length >= minLength && length <= maxLength;
    }

    /**
     * 校验统一社会信用代码
     */
    public static boolean isValidCreditCode(String creditCode) {
        if (isEmpty(creditCode)) {
            return false;
        }
        return CREDIT_CODE_PATTERN.matcher(creditCode.trim()).matches();
    }

    /**
     * 校验手机号码
     */
    public static boolean isValidPhone(String phone) {
        if (isEmpty(phone)) {
            return false;
        }
        return PHONE_PATTERN.matcher(phone.trim()).matches();
    }

    /**
     * 校验邮箱
     */
    public static boolean isValidEmail(String email) {
        if (isEmpty(email)) {
            return false;
        }
        return EMAIL_PATTERN.matcher(email.trim()).matches();
    }

    /**
     * 校验URL
     */
    public static boolean isValidUrl(String url) {
        if (isEmpty(url)) {
            return false;
        }
        return URL_PATTERN.matcher(url.trim()).matches();
    }

    /**
     * 校验数字字符串
     */
    public static boolean isValidNumber(String value) {
        if (isEmpty(value)) {
            return false;
        }
        try {
            new BigDecimal(value.trim());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 校验整数字符串
     */
    public static boolean isValidInteger(String value) {
        if (isEmpty(value)) {
            return false;
        }
        try {
            Integer.parseInt(value.trim());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 校验BigDecimal是否大于0
     */
    public static boolean isGreaterThanZero(BigDecimal value) {
        return value != null && value.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 校验BigDecimal是否大于等于0
     */
    public static boolean isGreaterThanOrEqualToZero(BigDecimal value) {
        return value != null && value.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * 校验日期字符串格式
     */
    public static boolean isValidDate(String value) {
        if (isEmpty(value)) {
            return false;
        }
        return DateUtil.parseDate(value.trim()) != null;
    }

    /**
     * 校验日期时间字符串格式
     */
    public static boolean isValidDateTime(String value) {
        if (isEmpty(value)) {
            return false;
        }
        return DateUtil.parseDateTime(value.trim()) != null;
    }

    /**
     * 校验是否在指定范围内
     */
    public static boolean isInRange(int value, int min, int max) {
        return value >= min && value <= max;
    }

    /**
     * 校验是否在指定范围内
     */
    public static boolean isInRange(BigDecimal value, BigDecimal min, BigDecimal max) {
        if (value == null || min == null || max == null) {
            return false;
        }
        return value.compareTo(min) >= 0 && value.compareTo(max) <= 0;
    }

    /**
     * 校验字符串是否包含指定字符
     */
    public static boolean contains(String value, String target) {
        if (isEmpty(value) || isEmpty(target)) {
            return false;
        }
        return value.contains(target);
    }

    /**
     * 校验字符串是否以指定前缀开头
     */
    public static boolean startsWith(String value, String prefix) {
        if (isEmpty(value) || isEmpty(prefix)) {
            return false;
        }
        return value.startsWith(prefix);
    }

    /**
     * 校验字符串是否以指定后缀结尾
     */
    public static boolean endsWith(String value, String suffix) {
        if (isEmpty(value) || isEmpty(suffix)) {
            return false;
        }
        return value.endsWith(suffix);
    }

    /**
     * 校验字符串是否匹配正则表达式
     */
    public static boolean matches(String value, String regex) {
        if (isEmpty(value) || isEmpty(regex)) {
            return false;
        }
        try {
            return value.matches(regex);
        } catch (Exception e) {
            log.warn("正则表达式匹配失败: {}", regex, e);
            return false;
        }
    }

    /**
     * 校验对象是否为空
     */
    public static boolean isNull(Object value) {
        return value == null;
    }

    /**
     * 校验对象是否不为空
     */
    public static boolean isNotNull(Object value) {
        return value != null;
    }

    /**
     * 校验集合是否为空
     */
    public static boolean isEmpty(List<?> list) {
        return list == null || list.isEmpty();
    }

    /**
     * 校验集合是否不为空
     */
    public static boolean isNotEmpty(List<?> list) {
        return !isEmpty(list);
    }

    /**
     * 校验集合大小是否在指定范围内
     */
    public static boolean isSizeInRange(List<?> list, int minSize, int maxSize) {
        if (list == null) {
            return false;
        }
        int size = list.size();
        return size >= minSize && size <= maxSize;
    }

    /**
     * 构建校验错误信息
     */
    public static String buildErrorMessage(String fieldName, String message) {
        return String.format("%s: %s", fieldName, message);
    }

    /**
     * 构建校验错误信息列表
     */
    public static List<String> buildErrorList(String... errors) {
        List<String> errorList = new ArrayList<>();
        for (String error : errors) {
            if (isNotEmpty(error)) {
                errorList.add(error);
            }
        }
        return errorList;
    }
}
